module metrics

contains

real function dist(x1,y1,x2,y2)
	implicit none
	real, intent(in) :: x1,y1,x2,y2

	dist = sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))
	!write(*,*) dist
end function dist

real function mydensity(mydensitysig, xsig, ysig, nhumans, r)

	implicit none

	integer, intent(in) :: nhumans
	real, intent(in), dimension(0:nhumans) :: xsig, ysig
	real, intent(in) :: r

	real, intent(out), dimension(0:nhumans) :: mydensitysig

	integer i, j, cnt	
	real max

	mydensity = 0

	do i = 1, nhumans

		mydensitysig(i) = 0

		do j = 1, nhumans
			if( (i .eq. j) .eqv. .false.  ) then
				if( dist(xsig(i), ysig(i), xsig(j), ysig(j)) < r )  then
					mydensitysig(i) = mydensitysig(i) + 1.0
				end if
			end if
		enddo
		mydensity = mydensity + mydensitysig(i)
	enddo

	max = 0
	
	do i = 1, nhumans
		if(mydensitysig(i) > max) then 
			max = mydensitysig(i)
		end if
	enddo
	
	mydensity = max !mydensity / nhumans

end function mydensity 


real function crowdpressure(crowdpressuresig, xsig, ysig, vsig, nhumans, r)

	implicit none

	integer, intent(in) :: nhumans
	real, intent(in), dimension(0:nhumans) :: xsig, ysig, vsig
	real, intent(in) :: r

	real, intent(out), dimension(0:nhumans) :: crowdpressuresig

	real, dimension(0:10) :: V

	integer i, j, cntV	
	real max

	crowdpressure = 0

	do i = 1, nhumans

		crowdpressuresig(i) = 0
		cntV = 0
		V(cntV) = vsig(i)
		cntV = cntV + 1

		do j = 0, nhumans
			if( (i .eq. j) .eqv. .false.  ) then
				if( dist(xsig(i), ysig(i), xsig(j), ysig(j)) < r )  then
					crowdpressuresig(i) = crowdpressuresig(i) + 1.0
					V(cntV) = vsig(j)
					cntV = cntV + 1
				end if
			end if
		enddo
		if(cntV > 1) then
			crowdpressuresig(i) = crowdpressuresig(i) * variance(V,cntV)
		else
			crowdpressuresig(i) = 0
		end if

		crowdpressure = crowdpressure + crowdpressuresig(i)
	enddo

	max = 0
	
	do i = 1, nhumans
		if(crowdpressuresig(i) > max) then 
			max = crowdpressuresig(i)
		end if
	enddo
	
	crowdpressure = max !mydensity / nhumans

end function crowdpressure 


real function variance(V,n)
	implicit none

	integer, intent(in) :: n
	real, intent(in), dimension(0:n) :: V

	real mean
	integer i
	
	mean = 0
	do i = 1, n
		mean = mean + V(i)
	enddo

	mean = mean / n

	variance = 0

	do i = 1, n
		variance = variance + (mean - V(i))*(mean - V(i))
	enddo

	variance = variance / (n)

end function variance 


real function mean(val, n)
	implicit none

	integer, intent(in) :: n
	real, intent(in), dimension(0:n) :: val

	integer i
	real tot

	tot = 0.0

	do i = 1, n
		tot = tot + val(i)
	enddo

	mean = tot/n		

end function mean

end module
